package com.yunhe.authority.service.authority.impl;

import com.github.stuxuhai.jpinyin.PinyinException;
import com.github.stuxuhai.jpinyin.PinyinHelper;
import com.yunhe.authority.domain.authority.*;
import com.yunhe.authority.domain.base.Area;
import com.yunhe.authority.domain.base.StationType;
import com.yunhe.authority.repository.authority.OrganizationRepository;
import com.yunhe.authority.repository.authority.ResourceTreeRepository;
import com.yunhe.authority.repository.authority.StationRepository;
import com.yunhe.authority.repository.authority.impl.StationDao;
import com.yunhe.authority.service.authority.FirmService;
import com.yunhe.authority.service.authority.RealStationService;
import com.yunhe.authority.service.authority.RoleService;
import com.yunhe.authority.service.authority.StationService;
import com.yunhe.authority.service.base.AreaService;
import com.yunhe.authority.service.base.SerialNumService;
import com.yunhe.authority.service.base.StationTypeService;
import com.yunhe.authority.util.MyHeaderUtil;
import com.yunhe.common.constant.AuthorityConsts;
import com.yunhe.common.exception.ArgumentErrorException;
import com.yunhe.common.exception.DatabaseProcessException;
import com.yunhe.common.exception.ObjectNotFoundException;
import com.yunhe.common.exception.UniqueConstraintsException;
import com.yunhe.common.model.DomainList;
import com.yunhe.common.model.PageParam;
import com.yunhe.common.util.DateTimeUtils;
import com.yunhe.common.util.QueryUtil;
import com.yunhe.common.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.yunhe.common.util.CollectionUtil;

import java.io.IOException;
import java.util.*;

/**
 * 电站Service
 * @author liuronglei
 */
@Service
public class StationServiceImpl implements StationService {

    @Autowired
    private StationRepository stationRepository;
    @Autowired
    private ResourceTreeRepository resourceTreeRepository;
    @Autowired
    private StationTypeService stationTypeService;
    @Autowired
    private FirmService firmService;
    @Autowired
    private AreaService areaService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private StationDao stationDao;

    @Autowired
    private SerialNumService serialNumService;

    @Autowired
    private RealStationService realStationService;

    @Autowired
    private MyHeaderUtil myHeaderUtil;

    @Autowired
    private OrganizationRepository organizationRepository;


    /**
     * 电站对象处理和判断
     * @param station 电站对象
     */
    private void processBeforeSave(Station station, Long firmId)
            throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException, IOException {
        //判断所属所属首页、电站类型、地区是否为空
//        if (station.getStationType() == null || station.getStationType().getCode() == null) {
//            throw new ArgumentErrorException("所属电站类型不能为空");
//        }
//        StationType stationType = stationTypeService.findByCode(station.getStationType().getCode());
//        Long stationTypeCode = station.getStationType().getCode();
        //判断电站代码、电站名称是否为空
        if (StringUtil.isEmpty(station.getEnterpriseFullName())) {
            throw new ArgumentErrorException("企业全称不能为空");
        }
        station.setFirmId(null);
        //Long areaCode = null;
//        if (station.getArea() != null && station.getArea().getCode() != null) {
//            areaCode = station.getArea().getCode();
//        }
        //判断单位下电站名称是否重复
        Station stationByTitle;
        if (station.getId() == null) {
            stationByTitle = stationRepository.findByFirmAndEnterpriseFullName(firmId, station.getTitle());
            if (stationByTitle != null) {
                throw new UniqueConstraintsException("已存在名称为" + station.getEnterpriseFullName() + "的项目");
            }
        } else if (station.getId() != null) {
            stationByTitle = stationRepository.findByFirmAndEnterpriseFullName(firmId, station.getTitle());
            if (stationByTitle != null && !stationByTitle.getId().equals(station.getId())) {
                throw new UniqueConstraintsException("已存在名称为" + station.getEnterpriseFullName() + "的项目");
            }
        }
//        //判断电站代码是否已存在
//        Station stationByCode = this.findByCode(station.getCode());
//        if (stationByCode != null) {
//            if (station.getId() == null || stationByCode.getId().longValue() != station.getId().longValue()) {
//                throw new UniqueConstraintsException("该电站代码已存在");
//            }
//        }
        //判断电站编号是否已存在
//        Station stationByName = this.findByName(station.getName());
//        if (stationByName != null) {
//            if (station.getId() == null || stationByName.getId().longValue() != station.getId().longValue()) {
//                throw new UniqueConstraintsException("该电站编号已存在");
//            }
//        }
        //绑定所属电站类型
//        if (stationTypeCode == -1) {
//            station.setStationType(null);
//        } else if (stationType != null) {
//            station.setStationType(stationType);
//        } else {
//            throw new ObjectNotFoundException("找不到所属电站类型");
//        }
//        if (areaCode != null) {
//            Area area = areaService.findByCode(areaCode);
//            station.setArea(area);
//        }
    }

    /**
     * 更新电站类型
     * @param id 电站ID
     * @param stationTypeId 电站类型ID
     */
    private void updateStationType(Long id, Long stationTypeId) throws ObjectNotFoundException {
        if (id != null) {
            stationRepository.unbindStationTypeById(id);
        }
        if (stationTypeId != null) {
            StationType StationType = stationTypeService.findByStationTypeId(stationTypeId);
            if (StationType == null) {
                throw new ObjectNotFoundException("找不到ID为" + stationTypeId + "的电站类型");
            }
            stationRepository.bindStationTypeById(id, stationTypeId);
        }
    }

    /**
     * 对电站列表进行排序
     * @param stationList 菜单列表
     */
    private void sortStations(List<Station> stationList) {
        if (stationList != null && stationList.size() > 0) {
            Collections.sort(stationList);
        }
    }

    /**
     * 新增电站
     * @param station 电站对象
     */
    @Override
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    public Station createStation(Station station, Long firmId)
            throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException, PinyinException, IOException {
        station.setId(null);
        //生成对应的项目编号
        if("2".equals(station.getSystem())){
            String yq = serialNumService.generateSerialNumberByModelCode("yq");
            station.setName(yq);
        }else if("3".equals(station.getSystem())){
            String yq = serialNumService.generateSerialNumberByModelCode("jq");
            station.setName(yq);
        }
        station.setProjectNo(serialNumService.generateSerialNumberByModelCode("PROJECT"));
        station.setSn(PinyinHelper.getShortPinyin(station.getEnterpriseFullName()).toUpperCase());
        station.setCreateTime(DateTimeUtils.format(DateTimeUtils.PATTERN.DATETIME.value(),new Date()));
        processBeforeSave(station, firmId);
        Station newStation = stationRepository.save(station);
        //绑定单位
        Firm firm = firmService.findByFirmId(firmId);
        if (firm != null) {
            firmService.bindStation(firm.getId(), newStation.getId());
        } else {
            throw new ObjectNotFoundException("找不到id为" + firmId + "的单位");
        }

        //绑定默认的两个角色
        Role role = new Role();
        role.setName("salesman");
        role.setTitle("业务员");
        role.setActivity("1");
        role.setLevel(1);
        role.setInitRole(true);
        roleService.createRole(null,newStation.getId(),null,role);
        Role rootRole = new Role();
        rootRole.setName("root");
        rootRole.setTitle("管理员");
        rootRole.setActivity("1");
        rootRole.setLevel(1);
        rootRole.setInitRole(true);
        roleService.createRole(null,newStation.getId(),null,rootRole);
        //stationRepository.bindRole(newStation.getId(),Arrays.asList("salesman","root"));
        Role merchantsTotalRole = new Role();
        merchantsTotalRole.setName("merchantsTotal");
        merchantsTotalRole.setTitle("招商总");
        merchantsTotalRole.setActivity("1");
        merchantsTotalRole.setLevel(1);
        merchantsTotalRole.setInitRole(true);
        roleService.createRole(null,newStation.getId(),null,merchantsTotalRole);
        Role planRole = new Role();
        planRole.setName("plan");
        planRole.setTitle("策划");
        planRole.setActivity("1");
        planRole.setLevel(1);
        planRole.setInitRole(true);
        roleService.createRole(null,newStation.getId(),null,planRole);
        Role investmentManagerRole = new Role();
        investmentManagerRole.setName("investmentManager");
        investmentManagerRole.setTitle("招商经理");
        investmentManagerRole.setActivity("1");
        investmentManagerRole.setLevel(1);
        investmentManagerRole.setInitRole(true);
        roleService.createRole(null,newStation.getId(),null,investmentManagerRole);

        //默认创建一个真实园区
//        RealStation realStation = new RealStation();
//        BeanUtils.copyProperties(newStation, realStation);
//        realStation.setId(null);
//        realStationService.creatRealStation(newStation.getId(), realStation);

        //默认创建一个组织
        Organization organization = new Organization();
        organization.setLevel(1);
        organization.setCreateTime(System.currentTimeMillis());
        organization.setName(newStation.getEnterpriseFullName());
        organization.setTitle(newStation.getEnterpriseFullName());
        Organization newOrganization = organizationRepository.save(organization);
        organizationRepository.organizationBindStation(newOrganization.getId(), newStation.getId());

        return newStation;
    }

    /**
     * 删除电站
     * @param id 电站对象ID
     */
    @Override
    @Transactional
    public void deleteStation(Long id) {
        stationRepository.deleteById(id);
    }

    /**
     * 更新电站（更新全部字段）
     * @param station 电站对象
     */
    @Override
    @Transactional
    public Station updateStation(Long firmCode, Station station)
            throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException, IOException {
        boolean exists = station.getId() != null && stationRepository.existsById(station.getId());
        if (!exists) {
            throw new ObjectNotFoundException("找不到ID为" + station.getId() + "的电站");
        }
        station.setSn(String.valueOf(System.currentTimeMillis()));
        processBeforeSave(station, firmCode);
        Station newStation = stationRepository.save(station);
        if (firmCode != null) {
            Firm firm = firmService.findByCode(firmCode);
            //stationRepository.unbindFirmByCode(newStation.getCode());
            firmService.bindStation(firm.getId(), newStation.getId());
        }
        return newStation;
    }

    /**
     * 更新电站（更新指定字段）
     * @param id 电站ID
     * @param code 电站代码
     * @param firmCode 单位代码
     * @param name 电站编号
     * @param title 电站名称
     * @param storageCapacity 储能装机容量
     * @param photovoltaicCapacity 光伏装机容量
     * @param windCapacity 风机装机容量
     * @param longitude 经度
     * @param latitude 纬度
     * @param sn 排序
     * @param productionTime
     * @param stationTypeCode 电站类型代码
     * @param areaCode 地区代码
     * @param activity 是否可用
     */
    @Override
    @Transactional
    public Station updateStation(Long id,
                                 Long code,
                                 Long firmCode,
                                 String name,
                                 String title,
                                 Double storageCapacity,
                                 Double photovoltaicCapacity,
                                 Double windCapacity,
                                 String longitude,
                                 String latitude,
                                 String sn,
                                 Date productionTime,
                                 Long stationTypeCode,
                                 Long areaCode,
                                 Boolean activity,
                                 String coordinateRange,
                                 String schematicDiagramBase64)
            throws ArgumentErrorException, ObjectNotFoundException, UniqueConstraintsException, IOException {
        Station station = this.findById(id);
        if (station == null) {
            throw new ObjectNotFoundException("找不到ID为" + id + "的电站");
        }
        //Optional.ofNullable(code).ifPresent(station::setCode);
        Optional.ofNullable(name).ifPresent(station::setName);
        Optional.ofNullable(title).ifPresent(station::setTitle);
//        Optional.ofNullable(storageCapacity).ifPresent(station::setStorageCapacity);
//        Optional.ofNullable(photovoltaicCapacity).ifPresent(station::setPhotovoltaicCapacity);
//        Optional.ofNullable(windCapacity).ifPresent(station::setWindCapacity);
//        Optional.ofNullable(longitude).ifPresent(station::setLongitude);
//        Optional.ofNullable(latitude).ifPresent(station::setLatitude);
//        Optional.ofNullable(sn).ifPresent(station::setSn);
//        Optional.ofNullable(productionTime).ifPresent(station::setProductionTime);
//        Optional.ofNullable(activity).ifPresent(station::setActivity);
//        Optional.ofNullable(coordinateRange).ifPresent(station::setCoordinateRange);
//        Optional.ofNullable(schematicDiagramBase64).ifPresent(station::setSchematicDiagramBase64);
        if (stationTypeCode != null) {
            StationType stationType = new StationType();
            stationType.setCode(stationTypeCode);
            //station.setStationType(stationType);
        }
        if (areaCode != null) {
            Area area = new Area();
            area.setCode(areaCode);
            //station.setArea(area);
        }
        station.setSn(String.valueOf(System.currentTimeMillis()));
        processBeforeSave(station, firmCode);
        Station newStation = stationRepository.save(station);
        if (firmCode != null) {
            Firm firm = firmService.findByCode(firmCode);
            //stationRepository.unbindFirmByCode(newStation.getCode());
            firmService.bindStation(firm.getId(), newStation.getId());
        }
        return newStation;
    }

    /**
     * 更新电站类型
     * @param id 电站ID
     * @param stationTypeId 电站类型ID
     */
    @Override
    public void updateStationTypeById(Long id, Long stationTypeId) throws ObjectNotFoundException {
        updateStationType(id, stationTypeId);
    }

    /**
     * 根据电站ID获得电站
     * @param id 电站ID
     */
    @Override
    public Station findById(Long id) {
        //Firm firm = firmService.findFirmByStationId(id);
        Station station = stationRepository.findById(id).orElse(null);
        //station.setFirmId(firm.getId());
        return station;
    }

    /**
     * 根据电站编号获得电站
     * @param name 电站编号
     */
    @Override
    public Station findByName(String name) {
        return stationRepository.findByName(name);
    }

    /**
     * 根据电站代码获得电站
     * @param code 电站代码
     */
    @Override
    public Station findByCode(Long code) {
        return stationRepository.findByCode(code);
    }

    /**
     * 根据条件获得电站列表
     * @param firmCode 单位代码
     * @param typeCode 类型代码
     * @param queryStr 查询条件
     * @param pageParam 分页条件
     */
    @Override
    public Iterable<Station> findStations(Long firmCode,
                                          Long typeCode,
                                          String queryStr,
                                          PageParam pageParam) {
        List<Map<String, Object>> mapList;
        String cypher = "match(f:Firm)-[]->(s:Station)-[]->(a:Area) where 1=1 ";
        if (firmCode != null) {
            cypher = cypher + " and f.code=" + firmCode + " ";
        }
        if (StringUtils.isNotEmpty(queryStr)) {
            cypher = cypher + "and f.title contains '" + queryStr + "' or s.title contains '"
                    + queryStr + "' or a.title contains '" + queryStr + "' ";
        }
        cypher = cypher + "with s,a match(s)-[]->(t:StationType) ";
        if (typeCode != null) {
            cypher = cypher + "where t.code=" + typeCode + " ";
        }
        cypher = cypher + "return s,a,t ";
        if (QueryUtil.needPaging(pageParam)) {
            int size = pageParam.getSize();
            int page = pageParam.getPage();
            String sort;
            Sort sort1 = QueryUtil.getSort(pageParam.getSort());
            if (sort1 != null) {
                List<String> sorts = pageParam.getSort();
                if (sorts.get(0).startsWith("-")) {
                    sort = sorts.get(0).replace("-", "s.");
                    sort = "-" + sort;
                } else {
                    sort = "s." + sorts.get(0);
                }
                cypher = cypher + "order by " + sort + " skip " + page * size + " limit " + size;
            } else {
                cypher = cypher + " skip " + page * size + " limit " + size;
            }
            mapList = stationDao.search(cypher);
        } else {
            if (pageParam != null && QueryUtil.getSort(pageParam.getSort()) != null) {
                List<String> sorts = pageParam.getSort();
                String sort;
                if (sorts.get(0).startsWith("-")) {
                    sort = sorts.get(0).replace("-", "s.");
                    sort = "-" + sort;
                } else {
                    sort = "s." + sorts.get(0);
                }
                cypher = cypher + "order by " + sort + " ";
                mapList = stationDao.search(cypher);
            } else {
                cypher = cypher + "order by s.sn desc";
                mapList = stationDao.search(cypher);
            }
        }
        List<Station> result = new ArrayList<>();
        for (Map<String, Object> map : mapList) {
            int i = 1;
            Station station = new Station();
            Area area = new Area();
            StationType stationType = new StationType();
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                if (i == 1) {
                    station = (Station) entry.getValue();
                } else if (i == 2) {
                    area = (Area) entry.getValue();
                } else if (i == 3) {
                    stationType = (StationType) entry.getValue();
                }
                i ++;
            }
//            station.setArea(area);
//            station.setStationType(stationType);
            result.add(station);
        }
        return result;
    }

    /**
     * 电站绑定资源
     * @param id 电站ID
     * @param type 资源类型
     * @param resourceId 资源ID
     */
    @Override
    @Transactional
    public void bindResource(Long id, String type, Long resourceId)
        throws ArgumentErrorException {
        Map<Long, Boolean> map = isBindStation(Arrays.asList(resourceId));
        boolean isBind = map.get(resourceId);
        if (isBind) {
            throw new ArgumentErrorException("ID为" + resourceId + "的设备以绑定电站");
        }
        resourceTreeRepository.bindResource(id, type, resourceId);
    }

    /**
     * 解绑资源
     * @param id 单位ID
     * @param resourceId 资源ID
     */
    @Override
    @Transactional
    public void unbindResource(Long id, Long resourceId) {
        resourceTreeRepository.unbindResource(id, resourceId);
    }

    /**
     * 批量更新资源绑定
     * @param id 单位ID
     * @param domainList 资源列表
     */
    @Override
    @Transactional
    public void updateResource(Long id, DomainList<ResourceTree> domainList)
            throws DatabaseProcessException {
        //先解绑
        resourceTreeRepository.unbindAllResources(id);
        //再绑定
        List<ResourceTree> list = domainList.getList();
        if (list != null && list.size() > 0) {
            for (ResourceTree resourceTree : list) {
                resourceTreeRepository.bindResource(id, resourceTree.getType(), resourceTree.getId());
            }
        }
    }

    /**
     * 根据电站ID获得资源树
     * @param id 电站ID
     * @param typeList 类型列表
     */
    @Override
    public Iterable<ResourceTree> findResourceTreeById(Long id, List<String> typeList) {
        List<ResourceTree> list;
        if (typeList != null && typeList.size() > 0) {
            list = (List<ResourceTree>)resourceTreeRepository.getResourceByStationIdAndType(id, typeList);
        } else {
            list = (List<ResourceTree>)resourceTreeRepository.getResourceByStationId(id);
        }
        Collections.sort(list);
        return list;
    }

    /**
     * 根据电站ID获得电站代码
     * @param id 电站ID
     */
    @Override
    public Long getStationCodeById(Long id) throws ObjectNotFoundException {
        Long stationCode = null;
        if (id != null) {
            Long firmCode = firmService.getFirmCodeById(id);
            if (firmCode != null && String.valueOf(firmCode).startsWith(String.valueOf(AuthorityConsts.FIRM_CODE.NZ.value()))) {
                stationCode = firmCode;
            } else {
                Station station = findById(id);
                if (station == null) {
                    throw new ObjectNotFoundException("找不到电站ID为" + id + "的电站");
                } else {
                    //stationCode = station.getCode();
                }
            }
        }
        return stationCode;
    }

    /**
     * 根据电站ID获得电站编号
     * @param id 电站ID
     */
    @Override
    public String getStationNameById(Long id) throws ObjectNotFoundException {
        String stationName = null;
        if (id != null) {
            Station Station = findById(id);
            if (Station == null) {
                throw new ObjectNotFoundException("找不到电站ID为" + id + "的电站");
            } else {
                stationName = Station.getName();
            }
        }
        return stationName;
    }

//    /**
//     *根据电站获取所属地区
//     * @param id 电站ID
//     */
//    public Iterable<Area> findAreaByid(Long id){
//        return areaService.findAreaByid(id);
//    }

    /**
     * 根据电站获得电站类型
     * @param id ID
     */
    @Override
    public StationType findStationTypeById(Long id) {
        return stationRepository.findStationTypeById(id);
    }

    /**
     * 根据电站类型获得电站
     * @param StationTypeId 电站类型ID
     */
    @Override
    public Iterable<Station> findStationsByStationTypeId(Long StationTypeId) {
        return stationRepository.findStationsByStationTypeId(StationTypeId);
    }

    /**
     * 判断设备是否被电站绑定
     * @param devIdList 设备ID列表
     */
    @Override
    public Map<Long, Boolean> isBindStation(List<Long> devIdList) {
        Map<Long, Boolean> map = new HashMap<>();
        for (Long id : devIdList) {
            Boolean flag = stationRepository.isBindStation(id);
            if (flag != null && flag) {
                map.put(id, flag);
            } else {
                map.put(id, false);
            }
        }
        return map;
    }

    /**
     * 根据设备查找所属电站
     * @param devCode 设备代码
     */
    @Override
    public Station findStationByDevCode(Long devCode) {
        return stationRepository.findStationByDevCode(devCode);
    }

    /**
     * 查找单位下未被电站绑定的设备
     * @param firmId 单位ID
     */
    @Override
    public Iterable<ResourceTree> findDevicesUnbindStation(Long firmId) {
        List<ResourceTree> devicesOfFirm = (List<ResourceTree>)resourceTreeRepository.getResourceByFirmId(firmId);
        List<ResourceTree> devicesOfStation = (List<ResourceTree>)resourceTreeRepository.getResourceIsBindStationByFirm(firmId);
        List<ResourceTree> list = new ArrayList<>();
        for (ResourceTree resourceTree : devicesOfFirm) {
            String type = resourceTree.getType();
            if ("Analog".equals(type) || "ConnectivityNode".equals(type) || null == type) {
                list.add(resourceTree);
            }
        }
        for (ResourceTree resourceTree : devicesOfStation) {
            for (ResourceTree tree : devicesOfFirm) {
                if (resourceTree.getId().longValue() == tree.getId()) {
                    list.add(tree);
                }
            }
        }
        devicesOfFirm.removeAll(list);
        return devicesOfFirm;
    }

    @Override
    public Long findTotalCount(Long firmCode, Long typeCode, String queryStr) {
        String cypher = "match(f:Firm)-[]->(s:Station)-[]->(a:Area) where 1=1 ";
        if (firmCode != null) {
            cypher = cypher + " and f.code=" + firmCode + " ";
        }
        if (StringUtils.isNotEmpty(queryStr)) {
            cypher = cypher + "and f.title contains '" + queryStr + "' or s.title contains '"
                    + queryStr + "' or a.title contains '" + queryStr + "' ";
        }
        cypher = cypher + "with s,a match(s)-[]->(t:StationType) ";
        if (typeCode != null) {
            cypher = cypher + "where t.code=" + typeCode + " ";
        }
        cypher = cypher + "return count(s) as count";
        List<Map<String, Object>> list = stationDao.search(cypher);
        if (list.size() > 0) {
            return (long)((int)list.get(0).get("count"));
        } else {
            return 0L;
        }
    }

    /**
     * 根据角色ID获得有权限的电站列表
     * @param roleId 角色ID
     */
    @Override
    public Iterable<Station> findByRoleId(Long roleId) {
        Role role = roleService.findByRoleId(roleId);
        if ("root".equals(role.getName())) {
            return stationRepository.findAll();
        } else {
            return stationRepository.findStationsByRoleId(roleId);
        }
    }

    /**
     * 根据角色ID获得可选电站列表
     * @param roleId 角色ID
     */
    @Override
    public Iterable<Station> findOptionalByRoleId(Long roleId) {
        Role role = roleService.findByRoleId(roleId);
        if ("root".equals(role.getName())) {
            return stationRepository.findAll();
        } else {
            return stationRepository.findOptionalStationsByRoleId(roleId);
        }
    }

    @Override
    public Iterable<Station> findByFirmId(Long firmId) {
//        Firm firm = firmService.findByFirmId(firmId);
//        if (firm != null && String.valueOf(firm.getCode()).startsWith(String.valueOf(AuthorityConsts.FIRM_CODE.NZ.value()))) {
//            Station station = new Station();
//            //station.setCode(firm.getCode());
//            station.setName(firm.getName());
//            station.setTitle(firm.getTitle());
//            station.setId(firm.getId());
//            List<Station> list = new ArrayList<>();
//            list.add(station);
//            return list;
//        }
        return stationRepository.findStationByFirmId(firmId);
    }

    @Override
    public Iterable<Station> findByTitleContaining(String title) {
        return stationRepository.findByTitleContaining(title);
    }

    @Override
    public Iterable<Station> findByCapacity(Double capacity) {
        return stationRepository.findByStorageCapacityOrPhotovoltaicCapacityOrWindCapacity(capacity, capacity, capacity);
    }

    /**
     * 根据代码列表获得电站列表
     * @param codeList 代码列表
     */
    @Override
    public Iterable<Station> findStationByCodes(List<Long> codeList) {
        return stationRepository.findStationByCodes(codeList);
    }

    @Override
    public Station findByResourceId(Long resId) {
        return stationRepository.findByResourceId(resId);
    }

    @Override
    public Iterable<Station> getStationsByRoleAndFirm(Long roleId, Long firmId) {
        Role role = roleService.findByRoleId(roleId);
        List<Station> stationsByFirm = (List<Station>)findByFirmId(firmId);
        List<Station> stationsByRole;
        if ("root".equals(role.getName())) {
            stationsByRole = (List<Station>)stationRepository.findAll();
        } else {
            stationsByRole = (List<Station>)findByRoleId(role.getId());
        }
        List<Station> result = new ArrayList<>();
        if (stationsByFirm != null && stationsByRole != null) {
            for (Station s : stationsByFirm) {
                for (Station station : stationsByRole) {
                    if (s.getId().longValue() == station.getId()) {
                        result.add(station);
                        continue;
                    }
                }
            }
        }
        Station nanziStation = getNanziStation(firmId);
        if (nanziStation != null) {
            result.add(nanziStation);
        }
        return result;
    }

    @Override
    public void bindCompany(Long id, Long companyId) {
        stationRepository.bindCompany(id, companyId);
    }

    @Override
    public void unbindCompany(Long id, Long companyId) {
        stationRepository.unbindCompany(id, companyId);
    }

    @Override
    public Iterable<Station> findByRoleIds(List<Long> roleIds) {
        return stationRepository.findStationsByRoleIds(roleIds);
    }

    @Override
    public Station updateStation(Long id, Long firmId,
                                 Project project) throws ObjectNotFoundException, UniqueConstraintsException, ArgumentErrorException, IOException {
        Station station = this.findById(id);
        if (station == null) {
            throw new ObjectNotFoundException("找不到ID为" + id + "的电站");
        }
        Optional.ofNullable(project.getEnterpriseFullName()).ifPresent(station::setEnterpriseFullName);
        Optional.ofNullable(project.getFormerName()).ifPresent(station::setFormerName);
        Optional.ofNullable(project.getCategory()).ifPresent(station::setCategory);
        Optional.ofNullable(project.getOperatingPeriod()).ifPresent(station::setOperatingPeriod);
        Optional.ofNullable(project.getPhone()).ifPresent(station::setPhone);
        Optional.ofNullable(project.getContactTitle()).ifPresent(station::setContactTitle);
        Optional.ofNullable(project.getContactPerson()).ifPresent(station::setContactPerson);
        Optional.ofNullable(project.getRegisteredCapital()).ifPresent(station::setRegisteredCapital);
        Optional.ofNullable(project.getCorporateLogo()).ifPresent(station::setCorporateLogo);
        Optional.ofNullable(project.getCorporateLogoThumbnail()).ifPresent(station::setCorporateLogoThumbnail);
        Optional.ofNullable(project.getBusinessRegisteredAddress()).ifPresent(station::setBusinessRegisteredAddress);
        Optional.ofNullable(project.getAddress()).ifPresent(station::setAddress);
        processBeforeSave(station, firmId);
        Station newStation = stationRepository.save(station);
        return newStation;
    }

    @Override
    public Station findByTitle(String title) {
       return stationRepository.findByTitle(title);
    }

    @Override
    public Station findStationByBindCompanyId(Long id) {
        return stationRepository.findStationByBindCompanyId(id);
    }

    @Override
    public Station findByEnterpriseFullName(String enterpriseFullName) {
        return stationRepository.findByEnterpriseFullName(enterpriseFullName);
    }

    @Override
    public List<ProjectData> findStationByLoginUser(Long firmId, Long stationId) throws ArgumentErrorException {
        List<ProjectData> result = new ArrayList<>();
        //获取当前登录人的信息
        User headerUser = myHeaderUtil.getHeaderUser();
        if(headerUser == null){
            throw new ArgumentErrorException("该用户登录信息已过期，请重新登录");
        }
        //判断当前登录的账号是单位账号还是园区账号
        List<Firm> firms = headerUser.getFirms();
        List<Station> stations = headerUser.getStations();
        if(firmId == null && stationId == null){
            if(!CollectionUtil.isEmpty(stations)){
                for (Station station : stations) {
                    ProjectData projectData = new ProjectData();
                    projectData.setId(station.getId());
                    projectData.setTitle(station.getEnterpriseFullName());
                    projectData.setType("station");
                    projectData.setSn(station.getSn());
                    result.add(projectData);
                }
            }
            if(!CollectionUtil.isEmpty(firms)) {
                for (Firm firm : firms) {
                    ProjectData projectData = new ProjectData();
                    projectData.setId(firm.getId());
                    projectData.setTitle(firm.getEnterpriseFullName());
                    projectData.setType("firm");
                    projectData.setSn(firm.getSn());
                    result.add(projectData);
                }
            }
        }else if(firmId == null && stationId != null){
            if(!CollectionUtil.isEmpty(stations)){
                for (Station station : stations) {
                    if(stationId.longValue() == station.getId().longValue()){
                        ProjectData projectData = new ProjectData();
                        projectData.setId(station.getId());
                        projectData.setTitle(station.getEnterpriseFullName());
                        projectData.setType("station");
                        projectData.setSn(station.getSn());
                        result.add(projectData);
                    }
                }
            }
        }else if(firmId != null && stationId == null){
            //todo 目前没有单位账号 先不做逻辑处理
        }
        //对集合针对每个ProjectData的sn首字母进行升序排序
        result.sort(Comparator.comparing(ProjectData::getSn));
//        Comparator comparator = Collator.getInstance(Locale.CHINA);
//        if(!CollectionUtil.isEmpty(result)){
//            result = (List<ProjectData>) result.stream().sorted(comparator).collect(Collectors.toList());
//        }
        return result;
    }

    @Override
    public List<Map<String, Object>> getAllFirmAndStation(String system) {
        List<Map<String,Object>> maps = new ArrayList<>();
        Iterable<Firm> firms = firmService.findBySystem(system);
        if(firms != null){
            for (Firm firm : firms) {
                Map<String,Object> map = new HashMap<>();
                map.put("id",firm.getId());
                map.put("title",firm.getEnterpriseFullName());
                map.put("type","firm");
                Iterable<Station> stations = stationRepository.findStationByFirmId(firm.getId());
                List<Map<String,Object>> childrenMap = new ArrayList<>();
                if(stations != null){
                    for (Station station : stations) {
                        Map<String,Object> stationMap = new HashMap<>();
                        stationMap.put("id",station.getId());
                        stationMap.put("title",station.getEnterpriseFullName());
                        stationMap.put("type","station");
                        childrenMap.add(stationMap);
                    }
                }
                map.put("children",childrenMap);
                maps.add(map);
            }
        }
        return maps;
    }

    @Override
    public Station findStationByRealStationId(Long realStationId) {
        return stationRepository.findStationByRealStationId(realStationId);
    }


    /**
     * 解绑电站下所有企业
     * @param id 单位ID
     */
    private void unbindAllCompanys(Long id) {
        stationRepository.unbindAllCompanys(id);
    }

    private Station getNanziStation(Long firmId) {
        Firm firm = firmService.findByFirmId(firmId);
        if (firm != null && String.valueOf(firm.getCode()).startsWith(String.valueOf(AuthorityConsts.FIRM_CODE.NZ.value()))) {
            Station station = new Station();
            station.setId(firmId);
            //station.setCode(firm.getCode());
            station.setName(firm.getName());
            station.setTitle(firm.getTitle());
            return station;
        } else {
            return null;
        }
    }




}
